Skip to content

fix(postgres): transpile DAY/MONTH/YEAR to EXTRACT [CLAUDE]#7798

Open
vjpovlitz wants to merge 1 commit into
tobymao:mainfrom
vjpovlitz:fix/postgres-day-month-year-extract
Open

fix(postgres): transpile DAY/MONTH/YEAR to EXTRACT [CLAUDE]#7798
vjpovlitz wants to merge 1 commit into
tobymao:mainfrom
vjpovlitz:fix/postgres-day-month-year-extract

Conversation

@vjpovlitz

Copy link
Copy Markdown

Summary

PostgreSQL has no scalar DAY / MONTH / YEAR functions — date parts are read via
EXTRACT(field FROM source). When transpiling from a dialect that does have them (e.g.
T-SQL), SQLGlot emitted the functions unchanged, producing invalid Postgres SQL.

This adds Postgres generator rules so exp.Day / exp.Month / exp.Year render as
EXTRACT(<part> FROM ...).

Reproduction

import sqlglot

# Before
sqlglot.transpile("SELECT DAY(d) FROM t", read="tsql", write="postgres")[0]
# -> 'SELECT DAY(d) FROM t'            # invalid: no DAY() function in Postgres

# After
# -> 'SELECT EXTRACT(DAY FROM d) FROM t'

MONTH and YEAR behave the same. EXTRACT is the standard Postgres construct for these
parts: https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT

Approach

  • The fix is generator-only: T-SQL already parses these into the dedicated exp.Day /
    exp.Month / exp.Year nodes, so only the Postgres output was wrong. Parsing and other
    dialects are untouched (tsql -> tsql still yields DAY(d)).
  • Rendering reuses the existing exp.Extract node rather than hand-built SQL, and the three
    rules share a small _extract_sql(part) factory in the style of the neighboring
    _date_add_sql(kind) helper.
  • Dialects that inherit the Postgres generator (Redshift, Materialize, RisingWave) also benefit;
    they likewise lack scalar DAY/MONTH/YEAR.

Test

tests/dialects/test_postgres.py::TestPostgres::test_extract_date_parts asserts the
T-SQL -> Postgres transpilation and that the EXTRACT form round-trips in Postgres.

Fixes #6220

@geooo109 geooo109 self-assigned this Jun 26, 2026
@geooo109

geooo109 commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

@vjpovlitz thanks for the PR, in order to transpile DAY, MONTH, YEAR we need furhter investigation/testing.

For example the input (tsql) can be a string value, which we can't transpile in postgres as is (we need on the parsing side of tsql to wrap the function argument with a TsOrDs_ expression). Moreover, the input can be be an integer value, which again we can't transpile in postgres as is. Check also the docs here

Let's first make an analysis on all of these cases/inputs ^ in order to know the exact semantics of these functions, then we can come up with a robust implementation that covers theses cases (or a part of them).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No conversion on Date functions when going from SQL Server to PostgreSQL.

2 participants